﻿
using System;

namespace MathService.Values
{
    /// <summary>
    /// Очередь с линейным доступом
    /// </summary>
    /// <typeparam name="T">Тип элементов очереди</typeparam>
    public class LinearQueue<T>
    {
        private readonly T[] f_Buffer;
        private readonly int f_Length;
        private int f_Offset;

        public int Length { get { return f_Length; } }

        public T this[int i]
        {
            get
            {
                if(i < 0 || i >= f_Length)
                    throw new ArgumentOutOfRangeException();
                return f_Buffer[(i + f_Offset) % f_Length];
            }
            set
            {
                if(i < 0 || i >= f_Length)
                    throw new ArgumentOutOfRangeException();
                f_Buffer[(i + f_Offset) % f_Length] = value;
            }
        }

        public LinearQueue(int Length) { f_Buffer = new T[f_Length = Length]; }

        public void Add(T t)
        {
            f_Buffer[f_Offset] = t;
            f_Offset++;
            f_Offset %= f_Length;
        }

        public T[] ToArray()
        {
            var result = new T[f_Length];
            Array.Copy(f_Buffer, f_Offset, result, 0, f_Length - f_Offset);
            Array.Copy(f_Buffer, 0, result, f_Length - f_Offset, f_Offset);
            return result;
        }
    }
}
